const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');
const MarketEnvironment = require('./core/MarketEnvironment');
const Asset = require('./core/Asset');
const MacroEvent = require('./core/MacroEvent');
const RetailInvestor = require('./investors/RetailInvestor');
const MarketMaker = require('./investors/MarketMaker');
const InstitutionalInvestor = require('./investors/InstitutionalInvestor');
const RandomStrategy = require('./strategies/RandomStrategy');
const TrendFollowingStrategy = require('./strategies/TrendFollowingStrategy');
const MeanReversionStrategy = require('./strategies/MeanReversionStrategy');
const GamblerStrategy = require('./strategies/GamblerStrategy');
const HerdBehaviorStrategy = require('./strategies/HerdBehaviorStrategy');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: "*", 
    methods: ["GET", "POST"],
    credentials: true,
    allowedHeaders: ["Content-Type"]
  },
  transports: ['websocket', 'polling'],
  allowEIO3: true,
  pingTimeout: 60000,
  pingInterval: 25000,
  upgradeTimeout: 30000,
  cookie: false
});

// 中间件
app.use(express.static(path.join(__dirname, '../public')));
app.use(express.json());
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Credentials', 'true');
  next();
});

// 存储市场实例
let market = null;
let simulationRunning = false;
let simulationInterval = null;
let bankruptInvestorCount = 0; // 破产投资者计数

// 市场配置
let marketConfig = {
  timeStep: 1,
  macroEventProbability: 0.1,
  investorGeneratorConfig: {
    entryRate: 0.2,
    investorTypes: [
      { type: 'RetailInvestor', weight: 0.7 },
      { type: 'MarketMaker', weight: 0.2 },
      { type: 'InstitutionalInvestor', weight: 0.1 }
    ],
    strategyDistribution: {
      RetailInvestor: [
        { strategy: 'RandomStrategy', weight: 0.4 },
        { strategy: 'TrendFollowingStrategy', weight: 0.3 },
        { strategy: 'MeanReversionStrategy', weight: 0.2 },
        { strategy: 'GamblerStrategy', weight: 0.1 }
      ],
      MarketMaker: [
        { strategy: 'RandomStrategy', weight: 1.0 }
      ],
      InstitutionalInvestor: [
        { strategy: 'TrendFollowingStrategy', weight: 0.5 },
        { strategy: 'MeanReversionStrategy', weight: 0.5 }
      ]
    }
  },
  initialInvestorCounts: {
    retail: 2,
    marketMaker: 1,
    institutional: 1
  },
  initialCapitals: {
    retail: 50000,
    marketMaker: 1000000,
    institutional: 10000000
  },
  // 资产配置
  assetConfig: {
    AAPL: {
      initialPrice: 150.00,
      totalShares: 1000000,
      institutionalCapital: 10000000,
      institutionalShares: 1000000
    },
    GOOG: {
      initialPrice: 2500.00,
      totalShares: 1000000,
      institutionalCapital: 10000000,
      institutionalShares: 1000000
    }
  },
  // 止盈止损配置
  takeProfitProbability: 0.3,
  stopLossProbability: 0.4,
  takeProfitThreshold: 0.15,
  stopLossThreshold: 0.10
};

// 创建市场环境
function createMarket() {
  market = new MarketEnvironment(marketConfig);

  // 添加资产 (根据配置设置不同的初始价格和波动性)
  const aaplConfig = marketConfig.assetConfig.AAPL;
  const googConfig = marketConfig.assetConfig.GOOG;
  
  const stockA = new Asset('AAPL', 'Apple Inc.', aaplConfig.initialPrice, { volatility: 0.02 });
  const stockB = new Asset('GOOG', 'Alphabet Inc.', googConfig.initialPrice, { volatility: 0.015 });

  market.addAsset(stockA);
  market.addAsset(stockB);

  // 获取资产ID列表
  const assetIds = Array.from(market.assets.keys());
  const asset1Id = assetIds[0] || 'AAPL';
  const asset2Id = assetIds[1] || 'GOOG';

  // 添加宏观事件
  const events = [
    // 只影响资产1的事件
    new MacroEvent({ name: 'AAPL新产品发布', type: 'technology', impact: 3, duration: 2, probability: 0.05, targetAssets: asset1Id }),
    new MacroEvent({ name: 'AAPL供应链问题', type: 'economic', impact: -2, duration: 3, probability: 0.03, targetAssets: asset1Id }),
    
    // 只影响资产2的事件
    new MacroEvent({ name: 'GOOG广告收入超预期', type: 'economic', impact: 4, duration: 2, probability: 0.05, targetAssets: asset2Id }),
    new MacroEvent({ name: 'GOOG面临监管审查', type: 'political', impact: -3, duration: 4, probability: 0.04, targetAssets: asset2Id }),
    
    // 影响两个资产的事件
    new MacroEvent({ name: '经济数据好于预期', type: 'economic', impact: 2, duration: 3, probability: 0.1, targetAssets: [asset1Id, asset2Id] }),
    new MacroEvent({ name: '地缘政治紧张', type: 'political', impact: -3, duration: 5, probability: 0.05, targetAssets: [asset1Id, asset2Id] }),
    new MacroEvent({ name: '央行降息', type: 'economic', impact: 4, duration: 2, probability: 0.05, targetAssets: [asset1Id, asset2Id] }),
    new MacroEvent({ name: '重大技术突破', type: 'technology', impact: 5, duration: 4, probability: 0.03, targetAssets: [asset1Id, asset2Id] }),
    
    // 影响所有资产的通用事件
    new MacroEvent({ name: '全球金融危机', type: 'economic', impact: -5, duration: 6, probability: 0.01, targetAssets: 'all' })
  ];

  events.forEach(event => market.addMacroEvent(event));

  // 添加初始投资者
  const { retail, marketMaker, institutional } = marketConfig.initialInvestorCounts;
  const { retail: retailCapital, marketMaker: marketMakerCapital, institutional: institutionalCapital } = marketConfig.initialCapitals;

  // 添加初始散户投资者
  for (let i = 0; i < retail; i++) {
    // 根据策略分布选择策略
    const strategyType = selectStrategy(marketConfig.investorGeneratorConfig.strategyDistribution.RetailInvestor);
    let strategy = null;
    
    switch (strategyType) {
      case 'RandomStrategy':
        strategy = new RandomStrategy();
        break;
      case 'TrendFollowingStrategy':
        strategy = new TrendFollowingStrategy();
        break;
      case 'MeanReversionStrategy':
        strategy = new MeanReversionStrategy();
        break;
      case 'GamblerStrategy':
        strategy = new GamblerStrategy();
        break;
      case 'HerdBehaviorStrategy':
        strategy = new HerdBehaviorStrategy();
        break;
      default:
        strategy = new RandomStrategy();
    }
    
    const investor = new RetailInvestor({ 
      name: `散户${i + 1}`, 
      capital: retailCapital,
      strategy: strategy,
      takeProfitProbability: marketConfig.takeProfitProbability,
      stopLossProbability: marketConfig.stopLossProbability,
      takeProfitThreshold: marketConfig.takeProfitThreshold,
      stopLossThreshold: marketConfig.stopLossThreshold
    });
    market.addInvestor(investor);
  }

  // 添加初始做市商
  for (let i = 0; i < marketMaker; i++) {
    const investor = new MarketMaker({ 
      name: `做市商${i + 1}`, 
      capital: marketMakerCapital,
      strategy: new RandomStrategy()
    });
    market.addInvestor(investor);
  }

  // 添加初始机构投资者（控股机构）
  for (let i = 0; i < institutional; i++) {
    const aaplInstitutional = new InstitutionalInvestor({ 
      name: `AAPL控股机构${i + 1}`, 
      capital: aaplConfig.institutionalCapital,
      strategy: new RandomStrategy(),
      totalShares: aaplConfig.institutionalShares,
      minMarketValueThreshold: 0.1
    });
    market.addInvestor(aaplInstitutional);
    
    const googInstitutional = new InstitutionalInvestor({ 
      name: `GOOG控股机构${i + 1}`, 
      capital: googConfig.institutionalCapital,
      strategy: new RandomStrategy(),
      totalShares: googConfig.institutionalShares,
      minMarketValueThreshold: 0.1
    });
    market.addInvestor(googInstitutional);
  }
  
  // 为每个资产创建初始卖单（上市过程）
  createInitialListings();
}

// 为每个资产创建初始卖单（上市过程）
function createInitialListings() {
  if (!market) return;
  
  // 遍历所有资产
  for (const [assetId, asset] of market.assets) {
    const currentPrice = asset.getPrice();
    const assetConfig = marketConfig.assetConfig[assetId];
    
    if (!assetConfig) continue;
    
    // 为每个机构投资者（控股机构）创建初始卖单
    for (const [investorId, investor] of market.investors) {
      if (investor instanceof InstitutionalInvestor && investor.name.includes(assetId)) {
        // 创建初始卖单，价格略高于当前价格
        const sellPrice = currentPrice * 1.02; // 高出2%
        const sellQuantity = Math.min(
          Math.floor(investor.totalShares * 0.1), // 卖出不超过总份额的10%
          Math.floor(investor.capital * 0.05 / sellPrice) // 不超过可用资金的5%
        );
        
        if (sellQuantity > 0) {
          const Order = require('./core/Order');
          const sellOrder = new Order(
            investor.id,
            assetId,
            'sell',
            sellPrice,
            sellQuantity,
            { orderType: 'limit' }
          );
          market.submitOrder(sellOrder);
        }
      }
    }
  }
}

// 启动模拟
function startSimulation() {
  if (simulationRunning) return;
  
  simulationRunning = true;
  if (!market) {
    createMarket();
  }
  
  simulationInterval = setInterval(() => {
    if (market) {
      market.advanceTime();
      
      // 清除破产投资者
      clearBankruptInvestors();
      
      const snapshot = market.getSnapshot();
      // 添加交易数据和破产投资者计数
      snapshot.tradeData = getTradeData();
      snapshot.bankruptInvestorCount = bankruptInvestorCount;
      io.emit('marketUpdate', snapshot);
    }
  }, 1000);
}

// 停止模拟
function stopSimulation() {
  simulationRunning = false;
  if (simulationInterval) {
    clearInterval(simulationInterval);
    simulationInterval = null;
  }
}

// 清除破产投资者
function clearBankruptInvestors() {
  if (!market) return;
  
  for (const [investorId, investor] of market.investors) {
    if (investor.getIsBankrupt()) {
      market.removeInvestor(investorId);
      bankruptInvestorCount++;
    }
  }
}

// 获取交易数据（用于图表）
function getTradeData() {
  if (!market) return {};
  
  const tradeData = {};
  for (const [assetId, orderBook] of market.orderBooks) {
    // 简化实现，实际应该从订单簿中提取买卖数据
    tradeData[assetId] = {
      buyVolume: Math.floor(Math.random() * 1000),
      sellVolume: Math.floor(Math.random() * 1000)
    };
  }
  return tradeData;
}

// 重置市场
function resetMarket() {
  stopSimulation();
  market = null;
  bankruptInvestorCount = 0;
}

// 处理WebSocket连接
io.on('connection', (socket) => {
  console.log('用户连接');
  
  // 发送初始市场状态
  if (market) {
    const snapshot = market.getSnapshot();
    snapshot.bankruptInvestorCount = bankruptInvestorCount;
    socket.emit('marketUpdate', snapshot);
  }
  
  // 处理开始模拟请求
  socket.on('startSimulation', () => {
    startSimulation();
  });
  
  // 处理停止模拟请求
  socket.on('stopSimulation', () => {
    stopSimulation();
  });
  
  // 处理重置市场请求
  socket.on('resetMarket', () => {
    resetMarket();
    socket.emit('marketReset');
  });
  
  // 处理配置更新请求
  socket.on('updateConfig', (config) => {
    marketConfig = { ...marketConfig, ...config };
    if (market) {
      // 更新现有市场配置
      Object.assign(market.config, config);
    }
  });
  
  // 处理断开连接
  socket.on('disconnect', (reason) => {
    console.log('用户断开连接:', reason);
  });
  
  // 处理连接错误
  socket.on('connect_error', (error) => {
    console.log('连接错误:', error);
  });
});

// API端点
app.get('/api/market', (req, res) => {
  if (market) {
    const snapshot = market.getSnapshot();
    snapshot.bankruptInvestorCount = bankruptInvestorCount;
    res.json(snapshot);
  } else {
    res.json({ error: '市场未初始化' });
  }
});

// 获取市场配置
app.get('/api/config', (req, res) => {
  res.json(marketConfig);
});

// 更新市场配置
app.post('/api/config', (req, res) => {
  marketConfig = { ...marketConfig, ...req.body };
  res.json({ message: '配置已更新', config: marketConfig });
});

// 启动模拟API
app.post('/api/control/start', (req, res) => {
  startSimulation();
  res.json({ message: '模拟已启动' });
});

// 停止模拟API
app.post('/api/control/stop', (req, res) => {
  stopSimulation();
  res.json({ message: '模拟已停止' });
});

// 重置市场API
app.post('/api/control/reset', (req, res) => {
  resetMarket();
  res.json({ message: '市场已重置' });
});

// 获取资产历史数据（用于K线图）
app.get('/api/assets/:assetId/history', (req, res) => {
  const assetId = req.params.assetId;
  if (market && market.assets.has(assetId)) {
    const asset = market.assets.get(assetId);
    const history = asset.getHistory();
    
    // 格式化为K线图数据
    const klineData = history.map(point => ({
      time: point.time,
      open: point.open,
      high: point.high,
      low: point.low,
      close: point.close,
      volume: point.volume
    }));
    
    res.json(klineData);
  } else {
    res.status(404).json({ error: '资产未找到' });
  }
});

// 导出订单簿数据
app.get('/api/orderbook/export', (req, res) => {
  if (market) {
    const orderBookData = market.exportAllOrderBooks();
    res.json(orderBookData);
  } else {
    res.status(404).json({ error: '市场未初始化' });
  }
});

// 启动服务器
const PORT = process.env.PORT || 3005;
server.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});

module.exports = { app, server };

/**
 * 根据权重分布选择策略
 * @param {Array} strategyDistribution - 策略分布数组
 * @returns {String} 策略类型
 */
function selectStrategy(strategyDistribution) {
  if (!strategyDistribution || strategyDistribution.length === 0) {
    return 'RandomStrategy';
  }
  
  // 计算总权重
  const totalWeight = strategyDistribution.reduce((sum, item) => sum + item.weight, 0);
  
  // 如果总权重为0，返回随机策略
  if (totalWeight <= 0) {
    return 'RandomStrategy';
  }
  
  // 生成随机数
  const random = Math.random() * totalWeight;
  
  // 根据权重选择策略
  let cumulativeWeight = 0;
  for (const item of strategyDistribution) {
    cumulativeWeight += item.weight;
    if (random <= cumulativeWeight) {
      return item.strategy;
    }
  }
  
  // 默认返回第一个策略
  return strategyDistribution[0].strategy;
}
